/*
 This file is part of BTStracker
		
    BTStracker is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    BTStracker is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Foobar.  If not, see <http://www.gnu.org/licenses/>.	
	author: azbest.pro (azbest.pro@gmail.com)
*/
package pl.vdl.azbest.mremote.com;

import gnu.io.SerialPort;

import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;

import pl.vdl.azbest.log.LoggingTheGathering;
import pl.vdl.azbest.mremote.Conf;
import pl.vdl.azbest.mremote.gui.GUIFacade;

public class CSConnected implements CState {
	private CConnect conn;

	private Logger logger = Logger.getLogger(getClass().getName());
	{
		LoggingTheGathering.addPath(getClass().getName());
	}

	public CSConnected(CConnect conn) {
		this.conn = conn;
	}

	public void connect() {
		conn
				.setState(CommState.CONNECTION_FAILURE,
						"You are already connected");
	}

	public void disconnect() {
		readon = false;

		//System.out.println("interrupte dsendt = " + readon);
		write("");

		try {

			// conn.setSerialPortReader(null);
			// conn.setSerialPortWriter(null);
			// GUIFacade.getInstance().getTextOutputStream().close();

			conn.getPortInputStream().close();

			conn.getPortOutputstream().close();

			conn.getSPort().getOutputStream().close();
			// conn.getSPort().sendBreak(conn.getSPort().getStopBits());
			conn.getSPort().close();

		} catch (IOException e) {
			conn.setState(CommState.DISCONNECTION_FAILURE,
					"Cant disconnect IOException ");
			e.printStackTrace();

		} finally {
			conn.getSPort().removeEventListener();
			conn.getSPort().close();

		}

		conn.setState(CommState.DISCONNECTED, "You are disconnected",
				conn.sDisconnected);

	}

	public void error() {
		// TODO Auto-generated method stub

	}

	public void timeout() {
		// TODO Auto-generated method stub

	}

	/** Starts reader that is working all the time we are connected . */
	public void openCommunication() {
		SerialPortReader reader = new SerialPortReader(conn
				.getPortInputStream());
		reader.addInputStream(GUIFacade.getInstance().getTextOutputStream());

		reader.addInputStream(conn.getMRStream());
		tSReader = new Thread(reader);

		// Thread tSWriter = new Thread(conn.getSerialPortWriter());
		tSReader.start();
		// tSWriter.start();
		// SerialPortReader serialPortReader = new SerialPortReader(conn
		// .getPortInputStream());
		// conn.setSerialPortReader(serialPortReader);

	}

	public void write(final String line) {
		logger.info("Moving from connected to communicate.");
		conn.setState(CommState.CONNECTED, "", conn.sCommunicate);
		((CSCommunicate) (conn.getState())).performWriting(line);
	}

	public void closeCommunication() {
		// InputStream os = GUIFacade.getInstance().getTextInputStream();

	}

	public void perform() {
	}

	public class SerialPortReader implements Runnable {
		private InputStream is;

		private TextOutputStream textOutputStream;

		private List<OutputStream> streams = new ArrayList<OutputStream>(0);

		public SerialPortReader(InputStream is) {
			this.is = is;

		}

		public void addInputStream(OutputStream is) {
			this.streams.add(is);
		}

		public void run() {
			readon = true;
			try {
				// is.skip(is.available());
				// textOutputStream.flush();
				is.read();
				for (OutputStream os : streams) {
					if (os instanceof TextOutputStream)
						textOutputStream = (TextOutputStream) os;

				}

				int buffer;
				//logger.info("Reading ........number of witing streams = "
					//	+ streams.size());
				while ((buffer = is.read()) != -1 && readon) {
					//logger.info("Something to read occured ...");

					for (OutputStream os : streams) {
						os.write(buffer);
					}
					////System.out.println("writing to textarea !" + buffer);
				}
			} catch (IOException e) {
				e.printStackTrace();

			}
			//System.out.println("Thread ends ..");
		}
	}

	private volatile boolean readon = true;

	private Thread tSReader;
}
